package pers.lipeng.gobang;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**
 * @author APengG
 * 五子棋
 */
public class GoBangGame extends JFrame {
    private static final Integer CHESS_BOARD_CELL_SIZE = 50;
    private static final Integer CHESS_BOARD_SIZE = 15;
    private ChessBoardCell[][] chessBoardCells =
            new ChessBoardCell[CHESS_BOARD_SIZE][CHESS_BOARD_SIZE];
    private JPanel gamePanel;
    public static void main(String[] args) {
        new GoBangGame();
    }
    public GoBangGame(){

        gamePanel = new JPanel();
        gamePanel.setBackground(Color.YELLOW);
        //棋盘
        for (int i = 0; i<CHESS_BOARD_SIZE ; i++){
            for(int j=0; j<CHESS_BOARD_SIZE; j++){
                ChessBoardCell chessBoardCell = ChessBoardCellFactory.createChessBoardCell(j,i);
                chessBoardCell.setPreferredSize(
                        new Dimension(CHESS_BOARD_CELL_SIZE,
                                CHESS_BOARD_CELL_SIZE));
                //棋盘背景图
                //上边框
                if(i == 0){
                    JLabel jLabel = new JLabel();
                    ImageIcon imageIcon = null;
                    if (j == 0){
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_left_top.png"));
                    }else if(j == CHESS_BOARD_SIZE - 1) {
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_right_top.png"));
                    }else{
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_top.png"));
                    }
                    jLabel.setIcon(imageIcon);
                    chessBoardCell.add(jLabel,BorderLayout.CENTER);
                }
                if(i == CHESS_BOARD_SIZE-1){
                    JLabel jLabel = new JLabel();
                    ImageIcon imageIcon = null;
                    if (j == 0){
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_left_bottom.png"));
                    }else if(j == CHESS_BOARD_SIZE - 1) {
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_right_bottom.png"));
                    }else{
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_bottom.png"));
                    }
                    jLabel.setIcon(imageIcon);
                    chessBoardCell.add(jLabel,BorderLayout.CENTER);
                }
                if(j == 0){
                    JLabel jLabel = new JLabel();
                    ImageIcon imageIcon = null;
                    if (i == 0){
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_left_top.png"));
                    }else if(i == CHESS_BOARD_SIZE - 1) {
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_left_bottom.png"));
                    }else{
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_left.png"));
                    }
                    jLabel.setIcon(imageIcon);
                    chessBoardCell.add(jLabel,BorderLayout.CENTER);
                }
                if(j == CHESS_BOARD_SIZE-1){
                    JLabel jLabel = new JLabel();
                    ImageIcon imageIcon = null;
                    if (i == 0){
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_right_top.png"));
                    }else if(i == CHESS_BOARD_SIZE - 1) {
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_right_bottom.png"));
                    }else{
                        imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_right.png"));
                    }
                    jLabel.setIcon(imageIcon);
                    chessBoardCell.add(jLabel,BorderLayout.CENTER);
                }
                if(i !=0 && j != 0 && i != CHESS_BOARD_SIZE-1 && j != CHESS_BOARD_SIZE-1){
                    JLabel jLabel = new JLabel();
                    ImageIcon imageIcon = new ImageIcon(getClass().getResource("/gobang/img/chess_board_center.png"));
                    jLabel.setIcon(imageIcon);
                    chessBoardCell.add(jLabel,BorderLayout.CENTER);
                }
                chessBoardCells[j][i] = chessBoardCell;
                gamePanel.add(chessBoardCell);
            }
        }
        gamePanel.setLayout(new GridLayout(CHESS_BOARD_SIZE,CHESS_BOARD_SIZE,0,0));
        gamePanel.addMouseListener(new GamePanelListener());

        this.getContentPane().add(gamePanel);
        this.setSize(700,700);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int x = screenSize.width - this.getWidth() >> 1;
        this.setLocation(x,0);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.pack();
    }

    class GamePanelListener implements MouseListener{
        @Override
        public void mouseClicked(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            int status = execFlag(x, y,false);
            if(status == 1){
                Integer check = null;
                while(true){
                    Point point = RoBootStragry.balckStragry(CHESS_BOARD_SIZE);
                    check = execFlag(point.x, point.y,true);
                    System.out.println("机器下棋："+point.x+","+point.y+","+check);
                    if (check == 1 || check == 2){
                        break;
                    }
                }

            }
        }

        @Override
        public void mousePressed(MouseEvent e) {

        }

        @Override
        public void mouseReleased(MouseEvent e) {

        }

        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }
    }

    private int execFlag(int x,int y,boolean isBoot){
        ChessBoardCell jpanel = null;
        if(isBoot){
            jpanel = chessBoardCells[x][y];
        }else{
            jpanel = (ChessBoardCell)gamePanel.getComponentAt(x,y);
        }
        Integer bodyX = jpanel.getBodyX();
        Integer bodyY = jpanel.getBodyY();
        if (jpanel.getComponentCount() > 0){
            for (Component component : jpanel.getComponents()) {
                if(component instanceof Flag){
                    if(!isBoot){
                        JOptionPane.showMessageDialog(null,"此处已有棋子");
                    }
                    return 0;
                }
            }
        }
        Flag flag = FlagFactory.createFlag(bodyX, bodyY);
        ImageIcon imageIcon = null;
        if(FlagFactory.current_flag_white){
            imageIcon = new ImageIcon(getClass().getResource("/gobang/img/black.png"));
        }else{
            imageIcon = new ImageIcon(getClass().getResource("/gobang/img/white.png"));
        }
        flag.setIcon(imageIcon);
        jpanel.add(flag,BorderLayout.CENTER,0);
        jpanel.revalidate();
        boolean ifWin = checkIfWin(bodyX, bodyY, flag.getColor());
        if(ifWin){
            String winner = "";
            if(flag.getColor() == Color.WHITE){
                winner = "白棋";
            }else{
                winner = "黑棋";
            }
            UIManager.put("OptionPane.yesButtonText","再来一局?");
            int option = JOptionPane.showConfirmDialog(
                    null,
                    "恭喜" + winner + "获胜",
                    "游戏结束",
                    JOptionPane.YES_NO_OPTION
            );
            if(option == JOptionPane.YES_NO_OPTION){
                dispose();
                new GoBangGame();
            }else if(option == JOptionPane.NO_OPTION ||
                    option == JOptionPane.CLOSED_OPTION ||
                    option == JOptionPane.CANCEL_OPTION){
                dispose();
            }
            gamePanel.removeMouseListener(new GamePanelListener());
        }
        return !FlagFactory.current_flag_white ? 1 : 2;
    }
    private boolean checkIfWin(int x,int y,Color color){
        //横向形式
        boolean ifXWin = checkXWin(x, y,color);
        //纵向形式
        boolean ifYWin = checkYWin(x,y,color);
        //斜向形式
        boolean ifXYLeftWin = checkXYLeftWin(x,y,color);
        boolean ifXYRightWin = checkXYRightWin(x,y,color);
        return ifXWin || ifYWin || ifXYLeftWin || ifXYRightWin;
    }
    private boolean checkXWin(int x,int y,Color color){
        //将自己先加入计数
        int count = 1;
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x + i, y,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x - i, y,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        System.out.println("count:"+count);
        if(count >= 5){
            return true;
        }
        return false;
    }
    private boolean checkYWin(int x,int y,Color color){
        int count = 1;
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x, y + i,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x, y - i,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        if(count >= 5){
            return true;
        }
        return false;
    }
    private boolean checkXYLeftWin(int x,int y,Color color){
        int count = 1;
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x + i, y + i,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x - i, y - i,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        if(count >= 5){
            return true;
        }
        return false;

    }
    private boolean checkXYRightWin(int x,int y,Color color){
        int count = 1;
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x + i, y - i,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        for(int i=1;i<=4;i++){
            boolean b = checkExistChess(x - i, y + i,color);
            if(b){
                count++;
            }else{
                break;
            }
        }
        if(count >= 5){
            return true;
        }
        return false;
    }
    private boolean checkExistChess(int x,int y,Color color){
        if(x < 0 || x > CHESS_BOARD_SIZE-1 ||
           y < 0 || y > CHESS_BOARD_SIZE - 1
        ){
            return false;
        }
        ChessBoardCell chessBoardCell = chessBoardCells[x][y];
        if(chessBoardCell.getComponentCount() > 0){
            for (Component component : chessBoardCell.getComponents()) {
                if(component instanceof Flag){
                    Flag flag = (Flag) component;
                    Color background = flag.getColor();
                    if(background == color){
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
